import { BadRequestException, Injectable, Logger } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Between, Repository } from 'typeorm';
import { readFileByPath } from './weather.util';
import { env } from '~/global/env';
import { IWeatherWarningContent } from './weather.model';
import { WeatherEntity } from './weather.entity';
import dayjs from 'dayjs';

@Injectable()
export class WeatherService {
  private readonly logger = new Logger(WeatherService.name);

  constructor(
    @InjectRepository(WeatherEntity)
    private readonly weatherRepository: Repository<WeatherEntity>
  ) {}
  /**
   * 获取文件路径
   * @returns 文件路径
   */
  getFilePath(): string {
    // 从环境变量获取文件路径，如果没有则使用默认值
    const basePath = env('DAILY_SYNC_WEATHER_DIR');
    return basePath;
  }

  /**
   * 读取文件
   * @returns 文件内容或文件列表
   */
  async readFile(): Promise<any> {
    const dirPath = this.getFilePath();

    if (!dirPath) {
      throw new BadRequestException('文件路径不存在');
    }

    const fileContent: IWeatherWarningContent[] = await readFileByPath(dirPath);

    // 存储文件内容到数据库
    await this.saveWeatherDataToDB(fileContent);

    return fileContent;
  }

  /**
   * 将天气预警数据保存到数据库
   * @param weatherData 天气预警数据列表
   */
  async saveWeatherDataToDB(weatherData: IWeatherWarningContent[]): Promise<void> {
    if (!weatherData || weatherData.length === 0) {
      this.logger.warn('没有要保存的天气数据');
      return;
    }

    try {
      // 遍历所有天气数据
      for (const item of weatherData) {
        const date = dayjs(item.date).toDate();

        const existingRecord = await this.weatherRepository.findOne({
          where: {
            fileName: item.fileName,
            date: date, // 确保日期比较时忽略时间部分
          },
        });

        if (existingRecord) {
          await this.weatherRepository.update(existingRecord.id, {
            name: item.name,
            riskLevel: item.riskLevelName,
            riskLevelCode: item.riskLevel,
            targetPopulation: item.vulnerableGroups,
            preventionSuggestion: item.advice,
            isTomorrow: item.isTomorrow,
          });

          this.logger.log(`更新天气记录: ${item.type} - ${item.date}`);
        } else {
          const newRecord = this.weatherRepository.create({
            code: item.type,
            name: item.name,
            fileName: item.fileName,
            date,
            riskLevel: item.riskLevelName,
            riskLevelCode: item.riskLevel,
            targetPopulation: item.vulnerableGroups,
            preventionSuggestion: item.advice,
            isTomorrow: item.isTomorrow,
          });
          await this.weatherRepository.save(newRecord);

          this.logger.log(`创建天气记录: ${item.type} - ${item.date}`);
        }
      }

      this.logger.log('天气数据保存完成');
    } catch (error) {
      this.logger.error('保存天气数据到数据库失败:', error);
      throw new BadRequestException('保存天气数据失败');
    }
  }

  /**
   * 获取当天和明天的天气信息
   * @returns 当天和明天的天气信息
   */
  async getTodayAndTomorrowWeather() {
    const todayStart = dayjs().startOf('day').toDate();
    const tomorrowEnd = dayjs().add(1, 'day').endOf('day').toDate();
    this.logger.log(
      `查询日期范围: ${dayjs(todayStart).format('YYYY-MM-DD HH:mm:ss')} 到 ${dayjs(
        tomorrowEnd
      ).format('YYYY-MM-DD HH:mm:ss')}`
    );

    let weatherData = await this.weatherRepository.find({
      where: {
        date: Between(todayStart, tomorrowEnd),
      },
      order: {
        date: 'ASC',
      },
    });

    if (weatherData.length === 0) {
      this.logger.warn('没有找到当天和明天的天气预警信息');

      // 如果没有找到当天和明天的数据，尝试扩大查询范围到前一天
      this.logger.log('扩大查询范围到前一天');
      const yesterdayStart = dayjs().subtract(1, 'day').startOf('day').toDate();
      weatherData = await this.weatherRepository.find({
        where: {
          date: Between(yesterdayStart, tomorrowEnd),
        },
        order: {
          date: 'ASC',
        },
      });

      if (weatherData.length === 0) {
        this.logger.warn('没有找到前一天到明天的天气预警信息');
        return [];
      }
    }

    return weatherData.map((item) => ({
      ...item,
      date: dayjs(item.date).format('YYYY-MM-DD'),
    }));
  }
}
